package com.gewu.advertisement.core.common


import android.util.Log
import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.apache.hc.client5.http.classic.methods.HttpGet
import org.apache.hc.client5.http.impl.classic.HttpClients
import java.io.IOException
import java.io.InputStream

/**
 * @author htt 2021/1/7
 */
internal object HttpClient : CoroutineScope by SupervisorLogScope<HttpClient>() {

    private val client = HttpClients.createDefault()
    private val objectMapper = JacksonFactory.objectMapper
    private const val TAG = "HttpClient"

    suspend inline fun <reified T> get(url: String): T {
        Log.i(TAG,"--> GET url:$url")
        val typeReference = jacksonTypeRef<T>()
        return withContext(Dispatchers.IO) {
            client.execute(HttpGet(url)) {
                if (it.code == 200) {
                    val result = objectMapper.readValue<T>(it.entity.content, typeReference)
                    Log.i(TAG,"<-- GET ${it.code} $url body:$result")
                    return@execute result
                } else {
                    Log.i(TAG,"<-- GET ${it.code} $url")
                    throw IOException("request fail, status code:${it.code}")
                }
            }
        }
    }

    suspend fun getStream(url: String, block: (InputStream) -> Unit) {
        Log.i(TAG,"--> GET $url")
        withContext(Dispatchers.IO) {
            client.execute(HttpGet(url)) {
                Log.i(TAG,"<-- GET ${it.code} $url")
                if (it.code == 200) {
                    block(it.entity.content)
                } else {
                    throw IOException("request fail, status code:${it.code}")
                }
            }
        }
    }

}

